package de.gbeine.java.depview.ui.component;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Set;

import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextField;
import javax.swing.ListSelectionModel;
import javax.swing.border.BevelBorder;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;

import com.google.common.eventbus.EventBus;
import com.jgoodies.forms.factories.FormFactory;
import com.jgoodies.forms.layout.ColumnSpec;
import com.jgoodies.forms.layout.FormLayout;
import com.jgoodies.forms.layout.RowSpec;

import de.gbeine.java.depview.event.AddFilterEvent;
import de.gbeine.java.depview.event.RemoveFilterEvent;

/**
 *
 * @author gbeine
 *
 */
public final class FilterPanel extends JPanel implements de.gbeine.java.depview.ui.controller.FilterPanel {

    /**
     *
     */
    private static final long serialVersionUID = 6175881678432532626L;
    /**
     *
     */
    private final JTextField textField;
    /**
     *
     */
    private final JList lstFilter;
    /**
     *
     */
    private final EventBus eventBus;
    /**
     *
     */
    private final FilterListModel filterListModel;

    /**
     * Create the panel.
     */
    public FilterPanel(final EventBus pEventBus) {
        super();
        this.eventBus = pEventBus;
        setLayout(new FormLayout(new ColumnSpec[] {
                FormFactory.RELATED_GAP_COLSPEC,
                ColumnSpec.decode("default:grow"),
                FormFactory.RELATED_GAP_COLSPEC,
                FormFactory.BUTTON_COLSPEC,
                FormFactory.RELATED_GAP_COLSPEC,
                FormFactory.BUTTON_COLSPEC,
                FormFactory.RELATED_GAP_COLSPEC,
                FormFactory.LABEL_COMPONENT_GAP_COLSPEC,},
            new RowSpec[] {
                FormFactory.RELATED_GAP_ROWSPEC,
                FormFactory.DEFAULT_ROWSPEC,
                FormFactory.RELATED_GAP_ROWSPEC,
                RowSpec.decode("default:grow"),
                FormFactory.RELATED_GAP_ROWSPEC,
                FormFactory.DEFAULT_ROWSPEC,
                FormFactory.RELATED_GAP_ROWSPEC,
                FormFactory.DEFAULT_ROWSPEC,
                FormFactory.RELATED_GAP_ROWSPEC,
                FormFactory.NARROW_LINE_GAP_ROWSPEC,}));

        this.filterListModel = new FilterListModel();

        this.lstFilter = new JList();
        this.lstFilter.addListSelectionListener(new ListSelectionListener() {
            public void valueChanged(final ListSelectionEvent e) {
                FilterPanel.this.changeSelected();
            }
        });
        this.lstFilter.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
        this.lstFilter.setBorder(new BevelBorder(BevelBorder.LOWERED, null, null, null, null));
        this.lstFilter.setModel(this.filterListModel);

        final JScrollPane scrollPane = new JScrollPane();
        scrollPane.setViewportView(this.lstFilter);
        add(scrollPane, "2, 4, 5, 1, fill, fill");

        this.textField = new JTextField();
        this.textField.setColumns(10);
        add(this.textField, "2, 6, 5, 1, fill, default");

        final JLabel lblFilter = new JLabel("Filter");
        add(lblFilter, "2, 2");

        final JButton btnAdd = new JButton("Add");
        btnAdd.addActionListener(new ActionListener() {
            public void actionPerformed(final ActionEvent e) {
                FilterPanel.this.addFilterAction();
            }
        });
        add(btnAdd, "4, 8");

        final JButton btnRemove = new JButton("Remove");
        btnRemove.addActionListener(new ActionListener() {
            public void actionPerformed(final ActionEvent e) {
                FilterPanel.this.removeFilterAction();
            }
        });
        add(btnRemove, "6, 8");
    }

    /**
     *
     * @param filter
     */
    public void setFilter(final Set<String> pFilter) {
        this.filterListModel.addElements(pFilter);
    }

    /**
     *
     * @param pFilter
     */
    public void addFilter(final String pFilter) {
        this.filterListModel.addElement(pFilter);
    }

    /**
     *
     * @param pFilter
     */
    public void removeFilter(final String pFilter) {
        this.filterListModel.removeElement(pFilter);
    }

    /**
     *
     */
    private void addFilterAction() {
        final String filter = this.textField.getText();
        if (filter.length() > 0) {
            this.filterListModel.addElement(filter);
            this.eventBus.post(new AddFilterEvent(this, filter));
        }
    }

    /**
     *
     */
    private void removeFilterAction() {
        final String filter = this.textField.getText();
        if (filter.length() > 0) {
            this.filterListModel.removeElement(filter);
            this.eventBus.post(new RemoveFilterEvent(this, filter));
        }
    }

    /**
     * Change text input field to selected element from list.
     */
    private void changeSelected() {
        final int index = this.lstFilter.getSelectedIndex();
        this.textField.setText((String) this.filterListModel.getElementAt(index));
    }
}
